<!--
 * @Author: zqx me_zqx@163.com
 * @Date: 2025-02-26 14:49:31
 * @LastEditors: zqx me_zqx@163.com
 * @LastEditTime: 2025-03-12 14:10:43
 * @FilePath: /XMate-h5/src/components/dateSelectView.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div class="date-select-wrapper" :class="{ 'popup-mode': isPopup }">
    <template v-if="!isPopup">
      <!-- 内嵌模式 -->
      <van-calendar
        v-bind="$attrs"
        :poppable="false"
        :show-confirm="true"
        :style="{ height: '500px' }"
        :default-date="selectedDate"
        type="range"
        :min-date="minDate"
        :max-date="maxDate"
        :formatter="formatter"
        @confirm="handleConfirm"
        @close="handleClose"
        @select="handleSelect"
      >
        <template #title>
          <div class="quick-select">
            <van-button
              size="small"
              :type="isActiveButton('year') ? 'primary' : 'default'"
              @click="handleQuickSelect('year')"
              >本年</van-button
            >
            <van-button
              size="small"
              :type="isActiveButton('quarter') ? 'primary' : 'default'"
              @click="handleQuickSelect('quarter')"
              >本季</van-button
            >
            <van-button
              size="small"
              :type="isActiveButton('month') ? 'primary' : 'default'"
              @click="handleQuickSelect('month')"
              >本月</van-button
            >
            <van-button
              size="small"
              :type="isActiveButton('week') ? 'primary' : 'default'"
              @click="handleQuickSelect('week')"
              >本周</van-button
            >
            <van-button
              size="small"
              :type="isActiveButton('last7days') ? 'primary' : 'default'"
              @click="handleQuickSelect('last7days')"
              >近7天</van-button
            >
            <van-button
              size="small"
              :type="isActiveButton('last30days') ? 'primary' : 'default'"
              @click="handleQuickSelect('last30days')"
              >近30天</van-button
            >
            <van-button
              size="small"
              :type="isActiveButton('last90days') ? 'primary' : 'default'"
              @click="handleQuickSelect('last90days')"
              >近90天</van-button
            >
          </div>
        </template>
      </van-calendar>
    </template>

    <!-- 弹框模式 -->
    <van-popup
      v-else
      v-model:show="popupVisible"
      position="bottom"
      round
      teleport="body"
      :style="{ height: '80%' }"
      @click-overlay="handleClose"
      @close="handleClose"
    >
      <div class="popup-content">
        <!-- 添加标题栏 -->
        <div class="popup-header">
          <div class="popup-title">选择日期</div>
          <van-icon name="cross" class="close-icon" @click="handleClose" />
        </div>

        <van-calendar
          v-bind="$attrs"
          :poppable="false"
          :show-confirm="true"
          :style="{ height: 'calc(100% - 60px)' }"
          :default-date="selectedDate"
          type="range"
          :min-date="minDate"
          :max-date="maxDate"
          :formatter="formatter"
          @confirm="handleConfirm"
          @close="handleClose"
          @select="handleSelect"
        >
          <template #title>
            <div class="quick-select">
              <van-button
                size="small"
                :type="isActiveButton('year') ? 'primary' : 'default'"
                @click="handleQuickSelect('year')"
                >本年</van-button
              >
              <van-button
                size="small"
                :type="isActiveButton('quarter') ? 'primary' : 'default'"
                @click="handleQuickSelect('quarter')"
                >本季</van-button
              >
              <van-button
                size="small"
                :type="isActiveButton('month') ? 'primary' : 'default'"
                @click="handleQuickSelect('month')"
                >本月</van-button
              >
              <van-button
                size="small"
                :type="isActiveButton('week') ? 'primary' : 'default'"
                @click="handleQuickSelect('week')"
                >本周</van-button
              >
              <van-button
                size="small"
                :type="isActiveButton('last7days') ? 'primary' : 'default'"
                @click="handleQuickSelect('last7days')"
                >近7天</van-button
              >
              <van-button
                size="small"
                :type="isActiveButton('last30days') ? 'primary' : 'default'"
                @click="handleQuickSelect('last30days')"
                >近30天</van-button
              >
              <van-button
                size="small"
                :type="isActiveButton('last90days') ? 'primary' : 'default'"
                @click="handleQuickSelect('last90days')"
                >近90天</van-button
              >
            </div>
          </template>
        </van-calendar>
      </div>
    </van-popup>
  </div>
</template>

<script>
import { Calendar, Button, Popup, Icon } from "vant";
import dayjs from "dayjs";

export default {
  name: "DateSelectView",

  components: {
    [Calendar.name]: Calendar,
    [Button.name]: Button,
    [Popup.name]: Popup,
    [Icon.name]: Icon,
  },

  props: {
    show: {
      type: Boolean,
      default: false,
    },
    isPopup: {
      type: Boolean,
      default: false,
    },
    defaultDate: {
      type: [Array, Date, String],
      default: null,
    },
  },

  data() {
    const now = dayjs();
    return {
      selectedDate: this.initDefaultDate(),
      minDate: now.subtract(5, "year").startOf("year").toDate(),
      maxDate: now.add(5, "year").endOf("year").toDate(),
      popupVisible: false,
    };
  },

  watch: {
    show: {
      handler(val) {
        if (this.isPopup) {
          this.popupVisible = val;
        }
      },
      immediate: true,
    },
    popupVisible(val) {
      if (!val) {
        this.$emit("update:show", false);
      }
    },
    defaultDate: {
      handler() {
        this.selectedDate = this.initDefaultDate();
      },
      immediate: true,
    },
  },

  methods: {
    initDefaultDate() {
      if (!this.defaultDate) return null;

      if (Array.isArray(this.defaultDate)) {
        return this.defaultDate.map((date) =>
          typeof date === "string" ? dayjs(date).toDate() : date
        );
      }

      return typeof this.defaultDate === "string"
        ? dayjs(this.defaultDate).toDate()
        : this.defaultDate;
    },

    formatter(day) {
      return day;
    },

    handleQuickSelect(type) {
      const now = dayjs();
      let startDate, endDate;

      switch (type) {
        case "year": {
          startDate = now.startOf("year").toDate();
          endDate = now.endOf("year").toDate();
          break;
        }
        case "quarter": {
          const currentMonth = now.month();
          const quarterStartMonth = Math.floor(currentMonth / 3) * 3;
          startDate = now.month(quarterStartMonth).startOf("month").toDate();
          endDate = now
            .month(quarterStartMonth + 2)
            .endOf("month")
            .toDate();
          break;
        }
        case "month": {
          startDate = now.startOf("month").toDate();
          endDate = now.endOf("month").toDate();
          break;
        }
        case "week": {
          startDate = now.startOf("week").add(1, "day").toDate();
          endDate = now.startOf("week").add(7, "day").endOf("day").toDate();
          break;
        }
        case "last7days": {
          startDate = now.subtract(6, "day").startOf("day").toDate();
          endDate = now.endOf("day").toDate();
          break;
        }
        case "last30days": {
          startDate = now.subtract(29, "day").startOf("day").toDate();
          endDate = now.endOf("day").toDate();
          break;
        }
        case "last90days": {
          startDate = now.subtract(89, "day").startOf("day").toDate();
          endDate = now.endOf("day").toDate();
          break;
        }
      }

      this.selectedDate = [startDate, endDate];
      //   this.$emit("confirm", [
      //     dayjs(startDate).format("YYYY-MM-DD"),
      //     dayjs(endDate).format("YYYY-MM-DD")
      //   ]);
    },

    handleConfirm(date) {
      this.selectedDate = date;
      if (Array.isArray(date)) {
        console.log("handleConfirm1", date);
        this.$emit("confirm", [
          dayjs(date[0]).format("YYYY-MM-DD"),
          dayjs(date[1]).format("YYYY-MM-DD"),
        ]);
      } else {
        console.log("handleConfirm2", date);
        this.$emit("confirm", dayjs(date).format("YYYY-MM-DD"));
      }

      if (this.isPopup) {
        this.popupVisible = false;
        this.$emit("update:show", false);
      }
    },

    handleClose() {
      if (this.isPopup) {
        this.popupVisible = false;
        this.$emit("update:show", false);
      }
      this.$emit("close");
    },

    isActiveButton(type) {
      if (!this.selectedDate || !Array.isArray(this.selectedDate)) return false;

      const startDate = dayjs(this.selectedDate[0]);
      const endDate = dayjs(this.selectedDate[1]);
      const now = dayjs();

      switch (type) {
        case "year": {
          const yearStart = now.startOf("year");
          const yearEnd = now.endOf("year");
          return (
            startDate.format("YYYY-MM-DD") === yearStart.format("YYYY-MM-DD") &&
            endDate.format("YYYY-MM-DD") === yearEnd.format("YYYY-MM-DD")
          );
        }
        case "quarter": {
          const currentMonth = now.month();
          const quarterStartMonth = Math.floor(currentMonth / 3) * 3;
          const quarterStart = now.month(quarterStartMonth).startOf("month");
          const quarterEnd = now.month(quarterStartMonth + 2).endOf("month");
          return (
            startDate.format("YYYY-MM-DD") === quarterStart.format("YYYY-MM-DD") &&
            endDate.format("YYYY-MM-DD") === quarterEnd.format("YYYY-MM-DD")
          );
        }
        case "month": {
          const monthStart = now.startOf("month");
          const monthEnd = now.endOf("month");
          return (
            startDate.format("YYYY-MM-DD") === monthStart.format("YYYY-MM-DD") &&
            endDate.format("YYYY-MM-DD") === monthEnd.format("YYYY-MM-DD")
          );
        }
        case "week": {
          const weekStart = now.startOf("week");
          const weekEnd = now.endOf("week");
          return (
            startDate.format("YYYY-MM-DD") === weekStart.format("YYYY-MM-DD") &&
            endDate.format("YYYY-MM-DD") === weekEnd.format("YYYY-MM-DD")
          );
        }
        case "last7days": {
          const last7Start = now.subtract(6, "day").startOf("day");
          const last7End = now.endOf("day");
          return (
            startDate.format("YYYY-MM-DD") === last7Start.format("YYYY-MM-DD") &&
            endDate.format("YYYY-MM-DD") === last7End.format("YYYY-MM-DD")
          );
        }
        case "last30days": {
          const last30Start = now.subtract(29, "day").startOf("day");
          const last30End = now.endOf("day");
          return (
            startDate.format("YYYY-MM-DD") === last30Start.format("YYYY-MM-DD") &&
            endDate.format("YYYY-MM-DD") === last30End.format("YYYY-MM-DD")
          );
        }
        case "last90days": {
          const last90Start = now.subtract(89, "day").startOf("day");
          const last90End = now.endOf("day");
          return (
            startDate.format("YYYY-MM-DD") === last90Start.format("YYYY-MM-DD") &&
            endDate.format("YYYY-MM-DD") === last90End.format("YYYY-MM-DD")
          );
        }
        default:
          return false;
      }
    },

    handleSelect(date) {
      this.selectedDate = date;
    },
  },
};
</script>

<style scoped>
.date-select-wrapper {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #fff;
}

.date-select-wrapper.popup-mode {
  height: auto;
}

.popup-content {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.popup-header {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  height: 44px;
  padding: 0 16px;
  background: #fff;
}

.popup-title {
  font-size: 16px;
  font-weight: 500;
  color: #323233;
}

.close-icon {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 22px;
  color: #969799;
  cursor: pointer;
}

.quick-select {
  padding: 10px 16px;
  display: flex;
  gap: 8px;
  background: #fff;
  border-bottom: 1px solid #eee;
  flex-wrap: wrap;
}

.quick-select .van-button {
  flex-shrink: 0;
}

:deep(.van-calendar__body) {
  height: 100%;
  overflow: auto;
}
</style>
